#pragma once
#include <vector>
#include <string>
#include <map>
#include <stdint.h>
#include "os/string.h"

using std::map;
using std::vector;
using std::string;

class JsonValue 
{
private:
	union MyVal
	{
		int64_t l;
		double  d;
		bool    b;
	};

	enum MyType
	{
		TYPE_STR = 10001,
		TYPE_DOUBLE,
		TYPE_BOOL,
		TYPE_LONG,
		TYPE_MAP,
		TYPE_ARRAY,
		TYPE_NONE,
	};

private:
	typedef vector<JsonValue> ValVec;
	typedef map<string, JsonValue> ValMap;

	string str_val_;
	MyVal  unn_val_;
	MyType val_type_;

	ValVec vec_val_;
	ValMap map_val_;

public:
	JsonValue();
	~JsonValue();

	JsonValue& operator[](const int idx);
	JsonValue& operator[](const char* key);

	size_t    size();

	bool    HasKey(const char* key);
	string  ToString();
	int64_t ToLong();
	double  ToDouble();
	bool    ToBool();
	bool    IsValid();

	void Reset();
	void SetValue(void* y_val);

private:
	void SetStr(char* str);
	void SetBool(bool b);
	void SetDouble(double d);
	void SetLong(int64_t l);
};

class JsonParser 
{
public:
	static bool Parse(const char* json_str, JsonValue* val);
};